package com.quanyan.runningriding.service.impl;

import com.quanyan.api.APIResponse;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.utils.DateUtils;
import com.quanyan.common.utils.DistanceUtil;
import com.quanyan.common.utils.StringUtil;
import com.quanyan.runningriding.constans.PublicConstans;
import com.quanyan.runningriding.entity.db.*;
import com.quanyan.runningriding.entity.vo.run.*;
import com.quanyan.runningriding.entity.vo.run.req.AnnualMileageVo;
import com.quanyan.runningriding.entity.vo.run.req.RunRecordVo;
import com.quanyan.runningriding.entity.vo.run.req.RunUserVo;
import com.quanyan.runningriding.entity.vo.run.resp.*;
import com.quanyan.runningriding.mapper.*;
import com.quanyan.runningriding.service.RunRecordService;
import com.quanyan.runningriding.util.CommonUtil;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * RunRecordServiceImpl
 *
 * @author Tu Chun
 * @date 2016/8/23
 */
@Service
public class RunRecordServiceImpl implements RunRecordService {
    @Autowired
    private TbRunRecordMapper tbRunRecordMapper;

    @Autowired
    private TbRunRecordDetailMapper tbRunRecordDetailMapper;

    @Autowired
    private RunRecordMapper runRecordMapper;

    @Autowired
    private TbRunUserMapper tbRunUserMapper;

    @Autowired
    private TbRunLevelMapper runLevelMapper;

    private final Logger log = LoggerFactory.getLogger(RunRecordServiceImpl.class);

    @Override
    public APIResponse<?> login(RunUserVo runUserVo) {
        TbRunUserExample tbRunUserExample = new TbRunUserExample();
        tbRunUserExample.createCriteria().andUserIdEqualTo(runUserVo.getUserId());
        List<TbRunUser> runUsers = tbRunUserMapper.selectByExample(tbRunUserExample);
        if (runUsers != null && runUsers.size() != 0) {
            return APIResponse.returnFail("已经记录用户信息");
        }
        TbRunUser tbRunUser = new TbRunUser();
        tbRunUser.setUserId(runUserVo.getUserId());
        tbRunUser.setNickname(runUserVo.getNickname());
        tbRunUser.setGender(runUserVo.getGender());
        tbRunUser.setPhoto(runUserVo.getPhoto());
        int i = tbRunUserMapper.insertSelective(tbRunUser);
        if (i > 0)
            return APIResponse.returnSuccess("登陆记录用户信息成功");
        else
            return APIResponse.returnFail("登陆记录用户信息异常");
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Integer insertRunRecord(RunRecordVo runRecordVo) {
        TbRunUser tbRunUser = new TbRunUser();
        tbRunUser.setUserId(runRecordVo.getUserId());
        TbRunUserExample tbRunUserExample = new TbRunUserExample();
        tbRunUserExample.createCriteria().andUserIdEqualTo(runRecordVo.getUserId());
        List<TbRunUser> tbRunUsers = tbRunUserMapper.selectByExample(tbRunUserExample);
        if (tbRunUsers.isEmpty()){
            return -2;
        }

        TbRunRecord tbRunRecord = new TbRunRecord();
        tbRunRecord.setDistance(runRecordVo.getDistance());
        tbRunRecord.setUserId(runRecordVo.getUserId());
        tbRunRecord.setUserNickname(runRecordVo.getUserNickname());
        tbRunRecord.setUserPhoto(runRecordVo.getUserPhoto());
        if (StringUtil.isBlankOrNull(runRecordVo.getRunName())&& runRecordVo.getLatLngs() != null && runRecordVo.getLatLngs().size()>0) {
            LatLngInfo latLngInfo=runRecordVo.getLatLngs().get(0);
            Double lat=latLngInfo.getLat();
            Double lng=latLngInfo.getLng();
            String location=DistanceUtil.getLocationInfoByLatLng(lat.toString(), lng.toString());
            tbRunRecord.setRunName(location);
        }else{
            tbRunRecord.setRunName(runRecordVo.getRunName());
        }
        tbRunRecord.setExerciseTime(runRecordVo.getExerciseTime());
        tbRunRecord.setStartTime(new Date(runRecordVo.getStartTime()));
        tbRunRecord.setEndTime(new Date(runRecordVo.getEndTime()));
        tbRunRecord.setCreateTime(new Date());
        tbRunRecord.setUpdateTime(new Date());
        List<PerkiloPaceInfo> perkiloPaceInfos = runRecordVo.getPerkiloPaces();


        //统计第42公里所耗时
        Long kilo42Time = 0l;
        if (perkiloPaceInfos.size() >= 42) {
            for (int i = 0; i < 42; i++) {
                kilo42Time += perkiloPaceInfos.get(i).getTime();
            }
        }
            if (kilo42Time < 0) {
                APIResponse.returnFail("42公里所耗时非法");
            }
            tbRunRecord.setKilo42Time(kilo42Time);
            int result1 = tbRunRecordMapper.insertSelective(tbRunRecord);

            TbRunRecordDetailWithBLOBs tbRunRecordDetail = new TbRunRecordDetailWithBLOBs();
            tbRunRecordDetail.setUserId(runRecordVo.getUserId());
            tbRunRecordDetail.setRunRecordId(tbRunRecord.getId());
            tbRunRecordDetail.setAvgPace(runRecordVo.getAvgPace());
            tbRunRecordDetail.setCadence(runRecordVo.getCadence());
            tbRunRecordDetail.setCalories(runRecordVo.getCalories());
            tbRunRecordDetail.setMaxPace(runRecordVo.getMaxPace());
            tbRunRecordDetail.setMinPace(runRecordVo.getMinPace());
            tbRunRecordDetail.setStepCount(runRecordVo.getStepCount());
            tbRunRecordDetail.setStride(runRecordVo.getStride());
            tbRunRecordDetail.setAltitude(runRecordVo.getAltitude());
            tbRunRecordDetail.setCumulativeClimb(runRecordVo.getCumulativeClimb());
            tbRunRecordDetail.setCreateTime(new Date());
            tbRunRecordDetail.setUpdateTime(new Date());
            List<LatLngInfo> latLngs = runRecordVo.getLatLngs();
            List<PermeterStrideInfo> permeterStrideInfos = runRecordVo.getPermeterStrides();
            List<PermeterAltitudeInfo> permeterAltitudeInfos = runRecordVo.getPermeterAltitudes();
            List<PermeterCadenceInfo> permeterCadenceInfos = runRecordVo.getPermeterCadences();

            tbRunRecordDetail.setLatLng(CommonUtil.getLatLngStr(runRecordVo.getLatLngs()))  ;
            tbRunRecordDetail.setPerkiloPaceInfo(CommonUtil.getPerKiloPaceInfoStr(runRecordVo.getPerkiloPaces()));
            tbRunRecordDetail.setPermeterStrideInfo(CommonUtil.getPermeterStrideInfoStr(runRecordVo.getPermeterStrides()));
            tbRunRecordDetail.setPermeterAltitudeInfo(CommonUtil.getPermeterAltitudeInfoStr(runRecordVo.getPermeterAltitudes()));
            tbRunRecordDetail.setPermeterCadenceInfo(CommonUtil.getPermeterCadenceInfoStr(runRecordVo.getPermeterCadences()));
            int result2 = tbRunRecordDetailMapper.insertSelective(tbRunRecordDetail);


            //更新用户等级
            if (result1 > 0 && result2 > 0) {
                Boolean b = updateUserLevel(runRecordVo.getUserId());
                if (!b)
                    return -1;
            }



        return tbRunRecord.getId();
    }


    @Override
    public APIResponse<MonthMileageVo> getMonthMileage(String userId) {
        MonthMileageVo monthMileageVo = runRecordMapper.getMonthMileage(userId);
        monthMileageVo.setTotalLevel((byte) runLevelMapper.countByExample(null));
        return APIResponse.returnSuccess(monthMileageVo);
    }

    @Override
    public APIResponse<TotalMileage> getTotalMileage(String userId) {
        TotalMileage totalMileage = runRecordMapper.getTotalMileage(userId);
        if (totalMileage != null)
            totalMileage.setTotalLevel((byte) runLevelMapper.countByExample(null));
        return APIResponse.returnSuccess(totalMileage);
    }

    @Override
    public PageObj<AnnualMileage> getAnnualMileage(AnnualMileageVo annualMileageVo) {
        String userId = annualMileageVo.getUserId();
        Integer years = annualMileageVo.getYears();
        Integer pageNum = annualMileageVo.getPageNum();
        Integer pageSize = annualMileageVo.getPageSize();
        if (years == null || years == 0) {
            years = DateUtils.getYear();
        }
        if (pageNum == null || pageNum == 0) {
            pageNum = 1;
        }
        if (pageSize == null || pageSize == 0) {
            pageSize = 20;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("userId", userId);
        map.put("years", years);
        map.put("pageStart", (pageNum - 1) * pageSize);
        map.put("pageSize", pageSize);
        List<RunRecordSimple> runRecordSimples = runRecordMapper.getAnnualMileage(map);
        short lastMonth = 0;
        if (runRecordSimples != null && runRecordSimples.size() != 0) {
            //取最后一条数据 得到最后一个月份
            RunRecordSimple runRecordSimple = runRecordSimples.get(runRecordSimples.size() - 1);
            if (runRecordSimple != null) {
                lastMonth = DateUtils.getMonth(runRecordSimple.getCreateTime().getTime());
            }
        }
        HashMap<String, Object> hashMap = new HashMap<String, Object>();
        hashMap.put("userId", annualMileageVo.getUserId());
        hashMap.put("years", annualMileageVo.getYears());
        hashMap.put("month", lastMonth);
        //获得月里程集合
        List<MonthMileage> monthMileageList = runRecordMapper.getMonthMileageList(hashMap);
        AnnualMileage annualMileage = new AnnualMileage();
        annualMileage.setYears(annualMileageVo.getYears());
        //年里程数
        Double yearMileage = 0.00;
        List<MonthMileages> monthMileages = new ArrayList<MonthMileages>();
        if (monthMileageList != null && monthMileageList.size() != 0) {
            for (int i = 0; i < monthMileageList.size(); i++) {
                MonthMileage monthMileage = monthMileageList.get(i);
                yearMileage += monthMileage.getMileageNum();
                MonthMileages monthMileages1 = new MonthMileages();

                List<RunRecordSimple> runRecordSimples1 = new ArrayList<RunRecordSimple>();
                for (int j = 0; j < runRecordSimples.size(); j++) {
                    RunRecordSimple runRecordSimple = runRecordSimples.get(j);
                    if (monthMileage.getMonth() == DateUtils.getMonth(runRecordSimple.getCreateTime().getTime())) {
                        runRecordSimples1.add(runRecordSimple);
                    }
                }

                monthMileages1.setMonthMileage(monthMileage);
                monthMileages1.setRunRecordSimples(runRecordSimples1);
                if (runRecordSimples1 != null && runRecordSimples1.size() > 0) {
                    monthMileages.add(monthMileages1);
                }

            }
        }
        if (monthMileages != null && monthMileages.size() > 0) {
            annualMileage.setMileageNum(yearMileage);
            annualMileage.setMonthMileages(monthMileages);
        }
        TbRunRecordExample tbRunRecordExample = new TbRunRecordExample();
        tbRunRecordExample.createCriteria().andUserIdEqualTo(annualMileageVo.getUserId());
        Integer total = tbRunRecordMapper.countByExample(tbRunRecordExample);
        return PageObj.create(total, annualMileageVo.getPageNum(), annualMileageVo.getPageSize(), annualMileage);
    }


    @Override
    public APIResponse<RunTrackDetail> trackDisplay(Integer runRecordId) {
        RunTrackDetailMap trackDetailMap = runRecordMapper.trackDisplay(runRecordId);
        RunTrackDetail trackDetail = CommonUtil.getRunTrackDetail(trackDetailMap);
        return APIResponse.returnSuccess(trackDetail);
    }

    @Override
    public APIResponse<RunRecordDetail> runRecordDetails(Integer runRecordId) {
        RunRecordDetailMap recordDetailMap = runRecordMapper.runRecordDetails(runRecordId);
        RunRecordDetail runRecordDetail = CommonUtil.getRunTrackDetail(recordDetailMap);
        return APIResponse.returnSuccess(runRecordDetail);
    }

    @Override
    public APIResponse<ChartDetail> chartDetails(Integer runRecordId) {
        ChartDetailMap chartDetailMap = runRecordMapper.chartDetails(runRecordId);
        ChartDetail chartDetail = CommonUtil.getchartDetail(chartDetailMap);
        return APIResponse.returnSuccess(chartDetail);
    }

    @Override
    public APIResponse<?> batchSynchroniseRunRecord(List<RunRecordVo> runRecordVos) {
        Integer result = 0;
        String userId = runRecordVos.get(0).getUserId();
        for (int k = 0; k < runRecordVos.size(); k++) {
            RunRecordVo runRecordVo = runRecordVos.get(k);
            TbRunRecord tbRunRecord = new TbRunRecord();
            tbRunRecord.setDistance(runRecordVo.getDistance());
            tbRunRecord.setUserId(runRecordVo.getUserId());
            tbRunRecord.setUserNickname(runRecordVo.getUserNickname());
            tbRunRecord.setUserPhoto(runRecordVo.getUserPhoto());
            if (StringUtil.isBlankOrNull(runRecordVo.getRunName())&& runRecordVo.getLatLngs() != null && runRecordVo.getLatLngs().size()>0) {
                LatLngInfo latLngInfo=runRecordVo.getLatLngs().get(0);
                Double lat=latLngInfo.getLat();
                Double lng=latLngInfo.getLng();
                String location=DistanceUtil.getLocationInfoByLatLng(lat.toString(), lng.toString());
                tbRunRecord.setRunName(location);
            }else{
                tbRunRecord.setRunName(runRecordVo.getRunName());
            }

            tbRunRecord.setExerciseTime(runRecordVo.getExerciseTime());
            tbRunRecord.setStartTime(new Date(runRecordVo.getStartTime()));
            tbRunRecord.setEndTime(new Date(runRecordVo.getEndTime()));
            tbRunRecord.setCreateTime(new Date());
            tbRunRecord.setUpdateTime(new Date());
            List<PerkiloPaceInfo> perkiloPaceInfos = runRecordVo.getPerkiloPaces();
            //统计第42公里所耗时
            Long kilo42Time = 0l;
            if (perkiloPaceInfos.size() >= 42) {
                for (int i = 0; i < 42; i++) {
                    kilo42Time += perkiloPaceInfos.get(i).getTime();
                }
            }
            tbRunRecord.setKilo42Time(kilo42Time);
            //List<PermeterAltitudeInfo> permeterAltitudeInfos = runRecordVo.getPermeterAltitudeInfos();


            int result1 = tbRunRecordMapper.insertSelective(tbRunRecord);

            TbRunRecordDetailWithBLOBs tbRunRecordDetail = new TbRunRecordDetailWithBLOBs();
            tbRunRecordDetail.setUserId(runRecordVo.getUserId());
            tbRunRecordDetail.setRunRecordId(tbRunRecord.getId());
            tbRunRecordDetail.setAvgPace(runRecordVo.getAvgPace());
            tbRunRecordDetail.setCadence(runRecordVo.getCadence());
            tbRunRecordDetail.setCalories(runRecordVo.getCalories());
            tbRunRecordDetail.setMaxPace(runRecordVo.getMaxPace());
            tbRunRecordDetail.setMinPace(runRecordVo.getMinPace());
            tbRunRecordDetail.setStepCount(runRecordVo.getStepCount());
            tbRunRecordDetail.setCreateTime(new Date());
            tbRunRecordDetail.setUpdateTime(new Date());
            List<LatLngInfo> latLngs = runRecordVo.getLatLngs();

            tbRunRecordDetail.setLatLng(CommonUtil.getLatLngStr(runRecordVo.getLatLngs()));
            tbRunRecordDetail.setPerkiloPaceInfo(CommonUtil.getPerKiloPaceInfoStr(runRecordVo.getPerkiloPaces()));
            int result2 = tbRunRecordDetailMapper.insertSelective(tbRunRecordDetail);
            if (k == runRecordVos.size() - 1) {
                result = tbRunRecord.getId();
            }
        }
        //更新用户等级
        if (result > 0) {
            Boolean b = updateUserLevel(userId);
            if (!b)
                APIResponse.returnFail("更新用户等级异常");
        }

        return APIResponse.returnSuccess(result);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    private Boolean updateUserLevel(String userId) {
        //获取运动大于等于42Km的次数
        TbRunRecordExample tbRunRecordExample = new TbRunRecordExample();
        tbRunRecordExample.createCriteria()
                .andUserIdEqualTo(userId).andDistanceGreaterThanOrEqualTo(PublicConstans.RUN_KILO42);
        Integer kilo42Times = tbRunRecordMapper.countByExample(tbRunRecordExample);
        kilo42Times = kilo42Times != null ? kilo42Times : 0;
        //获取总里程
        /*Double totalMileage=runRecordMapper.userTotalMileage(userId);
        totalMileage=totalMileage!=null?totalMileage:0.00;*/
        Map<String, Object> hashMap = runRecordMapper.userTotalMileage(userId);
        Double totalMileage = MapUtils.getDouble(hashMap, "totalMileage");
        totalMileage = totalMileage != null ? totalMileage : 0.00;
        //获取42公里最小时间
        Long kilo42MinTime = runRecordMapper.kilo42MinTime(userId);
        kilo42MinTime = kilo42MinTime != null ? kilo42MinTime : 0;

        //获取用户等级
        TbRunLevelExample tbRunLevelExample = new TbRunLevelExample();
        tbRunLevelExample.createCriteria().andTotalMileageLessThanOrEqualTo(totalMileage)
                .andKilo42TimesLessThanOrEqualTo(kilo42Times)
                .andKilo42Time2GreaterThanOrEqualTo(kilo42MinTime);
        tbRunLevelExample.setOrderByClause(" level_id DESC ");
        List<TbRunLevel> runLevels = runLevelMapper.selectByExample(tbRunLevelExample);
        int i = 0;
        if (runLevels != null && runLevels.size() > 0) {
            TbRunLevel tbRunLevel = runLevels.get(0);
            TbRunUser tbRunUser = new TbRunUser();
            tbRunUser.setUserLevel(tbRunLevel.getLevelId().byteValue());
            TbRunUserExample tbRunUserExample = new TbRunUserExample();
            tbRunUserExample.createCriteria().andUserIdEqualTo(userId);
            log.warn("totalMileage:" + totalMileage + "  kilo42Times:" + kilo42MinTime + "  kilo42Time:" + kilo42MinTime + "    =====>>>" + tbRunLevel.getLevelId().byteValue());
            i = tbRunUserMapper.updateByExampleSelective(tbRunUser, tbRunUserExample);
        }

        if (i > 0)
            return true;
        else
            return false;
    }
}